// Code by:
// Quinten Lansu (knight666)
// Copyright 2008-2012

#ifndef _TBTIMER_H_
#define _TBTIMER_H_

#include "TBSettings.h"

#include <windows.h>
#include <mmsystem.h>

namespace tb
{

	class TB_DLL_FUNC TimerBase
	{

	public:

		TimerBase(unsigned int a_Samples);
		~TimerBase();

		virtual void Start() = 0;
		virtual void End() = 0;
		
		inline bool IsUpdated() const { return m_AverageUpdated; }

		inline float GetAverage() const { return m_Average; }

		inline float GetFPS() const { return m_FramesPerSecond; }

	protected:

		unsigned int m_Samples;
		unsigned int m_SamplesFilled;
		float m_Total;
		float m_Average;
		float m_FramesPerSecond;
		bool m_AverageUpdated;

	}; // class TimerBase

	class TimerLow : public TimerBase
	{

	public:

		TimerLow(unsigned int a_Samples = 1);
		~TimerLow();

		void Start();
		void End();

	protected:

		unsigned long m_TimeStart, m_TimeTotal;

	}; // class TimerLow

	class TimerMedium : public TimerBase
	{

	public:

		TimerMedium(unsigned int a_Samples = 1);
		~TimerMedium();

		void Start();
		void End();

	protected:

		unsigned long m_TimeStart, m_TimeTotal;

	}; // class TimerMedium

	class TimerHigh : public TimerBase
	{

	public:

		TimerHigh(unsigned int a_Samples = 1);
		~TimerHigh();

		void Start();
		void End();

	protected:

		LARGE_INTEGER m_TimeStart, m_TimeEnd;
		__int64 m_TimeTotal;
		float m_Frequency;

	}; // class TimerHigh

#ifdef TB_TIMER_PRECISION
#	if (TB_TIMER_PRECISION == TB_TIMER_PRECISION_HIGH)
		typedef TimerHigh Timer;
#	elif (TB_TIMER_PRECISION == TB_TIMER_PRECISION_NORMAL)
		typedef TimerMedium Timer;
#	elif (TB_TIMER_PRECISION == TB_TIMER_PRECISION_LOW)
		typedef TimerLow Timer;
#	endif
#else
	typedef TimerLow Timer;
#endif

}; // namespace tb

#endif